#import "ALGPSManager.h"
#import "UIAlertView+Blocks.h"
@interface ALGPSManager() <CLLocationManagerDelegate>

@property (nonatomic, strong) CLLocationManager *locationManager;
@property (nonatomic, assign) BOOL didFindLocation;
@property (nonatomic, assign) BOOL isAccurateGPS;

@property (nonatomic, weak) UIAlertView *alertView;

@end

@implementation ALGPSManager

static ALGPSManager *_instance = nil;

+ (instancetype)sharedInstance {
    static dispatch_once_t once_token;
    dispatch_once(&once_token, ^{
        _instance = [[ALGPSManager alloc] init];
    });
    return _instance;
}

- (id)init {
    if(self = [super init]) {
        if ([CLLocationManager significantLocationChangeMonitoringAvailable]) {
            self.locationManager = [[CLLocationManager alloc] init];
            [self.locationManager setDelegate:self];
            if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
                [self.locationManager requestWhenInUseAuthorization];
            }
        }
    }
    return self;
}

+ (BOOL)allowsToFetchLocation {
    CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
    if (status == kCLAuthorizationStatusAuthorizedAlways ||
        status == kCLAuthorizationStatusAuthorizedWhenInUse) {
        return YES;
    }
    
    return NO;
}

#pragma mark - GPS
- (void)start {
    if ([CLLocationManager significantLocationChangeMonitoringAvailable]) {
        self.isAccurateGPS = NO;
        [self.locationManager startMonitoringSignificantLocationChanges];
    }
}

- (void)stop {
    [self.locationManager stopMonitoringSignificantLocationChanges];
}

- (void)getGPS {
    self.isAccurateGPS = YES;
    _didFindLocation = NO;

    // 停止Monitor Significant Change
    [self.locationManager stopMonitoringSignificantLocationChanges];
    self.locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
    self.locationManager.distanceFilter = 200; // meters

    [self.locationManager startUpdatingLocation];
}

#pragma mark - GPS
//定位代理经纬度回调
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
    if (self.isAccurateGPS) {
        if (_didFindLocation) {
            return;
        }
        if (_getGPSSuccess != nil) {
            _getGPSSuccess(locations[0]);
        }
        _didFindLocation = YES;
        [manager stopUpdatingLocation];
        /// 开启模糊定位，用于HTTP header中带上经纬度信息
        [self start];
    }
}

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
    if (self.isAccurateGPS) {
        if (_didFindLocation) {
            return;
        }
        if (status == kCLAuthorizationStatusAuthorizedWhenInUse) {
            _alertView.didDismissBlock = nil;
            [_alertView dismissWithClickedButtonIndex:_alertView.cancelButtonIndex animated:NO];
            _alertView = nil;
        }
    }
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
    if (self.isAccurateGPS) {
        if (_didFindLocation) {
            return;
        }
        [manager stopUpdatingLocation];
        if ([error code] == kCLErrorDenied) {
            if (_alertView == nil) {
                
                UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"GPS_not_auth_alert_title"
                                                                    message:@"GPS_not_auth_alert_content"
                                                                   delegate:self
                                                          cancelButtonTitle:@"GPS_alert_cancel" otherButtonTitles:@"GPS_not_auth_alert_confirm", nil];
                _alertView = alertView;
                __weak typeof(self) weakSelf = self;
                alertView.didDismissBlock = ^(UIAlertView * _Nonnull alertView, NSInteger buttonIndex) {
                    if (buttonIndex == alertView.firstOtherButtonIndex) {
                        NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
                        if( [[UIApplication sharedApplication]canOpenURL:url] ) {
                            [[UIApplication sharedApplication]openURL:url];
                        }
                        [weakSelf.locationManager performSelector:@selector(startUpdatingLocation) withObject:nil afterDelay:3.0f];
                    } else if (buttonIndex == alertView.cancelButtonIndex) {
                        if (weakSelf.getGPSNoPermission != nil) {
                            weakSelf.getGPSNoPermission(nil);
                        }
                    }
                };
                [alertView show];
            }
        } else {
            if (_getGPSFail != nil) {
                _getGPSFail(nil);
            }
        }
    }
}

+ (CLLocation *)currentLocation {
    return _instance.locationManager.location;
}

@end
